﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class ForEachStatement : BodiedStatement
{
    private readonly SyntaxToken _eachKeywordToken;


    private readonly SyntaxToken _forKeywordToken;
    private Identifier _elementIdentifier;
    private Expression _groupExpression;
    private SyntaxToken _inKeywordToken;
    private SyntaxToken _nextKeywordToken;

    internal ForEachStatement(SyntaxToken forKeywordToken, SyntaxToken eachKeywordToken, SyntaxNode? parent) :
        base(SyntaxKinds.ForEachStatement, parent)
    {
        SetChildField(ref _forKeywordToken, forKeywordToken);
        SetChildField(ref _eachKeywordToken, eachKeywordToken);
        _elementIdentifier = Identifier.Default;
        _inKeywordToken = SyntaxToken.Default;
        _groupExpression = EmptyExpression.Default;
        _nextKeywordToken = SyntaxToken.Default;
    }


    public SyntaxToken ForKeywordToken => _forKeywordToken;

    public SyntaxToken EachKeywordToken => _eachKeywordToken;

    public SyntaxToken InKeywordToken => _inKeywordToken;

    public SyntaxToken NextKeywordToken => _nextKeywordToken;

    public Identifier ElementIdentifier => _elementIdentifier;

    public Expression GroupExpression => _groupExpression;


    public ForEachStatement Update(Identifier elementIdentifier, SyntaxToken inKeywordToken,
        Expression groupExpression)
    {
        Debug.Assert(inKeywordToken.IsNode(SyntaxKinds.InKeywordToken));
        SetChildField(ref _elementIdentifier, Identifier.IsDefaultOrEmpty, elementIdentifier);
        SetChildField(ref _inKeywordToken, SyntaxToken.IsNullOrEmpty, inKeywordToken);
        SetChildField(ref _groupExpression, Expression.IsEmptyExpression, groupExpression);
        return this;
    }


    public void Update(SyntaxToken nextKeywordToken)
    {
        Debug.Assert(nextKeywordToken.IsNode(SyntaxKinds.NextKeywordToken));
        SetChildField(ref _nextKeywordToken, SyntaxToken.IsNullOrEmpty, nextKeywordToken);
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, ForKeywordToken, EachKeywordToken,
            ElementIdentifier, InKeywordToken, GroupExpression, NextKeywordToken);
        base.AcceptVisitor(visitor);
    }
}


public static partial class NodeFactory
{
    public static ForEachStatement CreateForEachStatement(SyntaxNode? parent, SyntaxToken forKeywordToken,
        SyntaxToken eachKeywordToken)
    {
        Debug.Assert(forKeywordToken.IsNode(SyntaxKinds.ForKeywordToken));
        Debug.Assert(eachKeywordToken.IsNode(SyntaxKinds.EachKeywordToken));
        return new ForEachStatement(forKeywordToken, eachKeywordToken, parent);
    }
}